# -*- encoding: utf-8 -*-

"""
@File:      tc_lmdb_lmdb_func_004.py
@Time:      2024/03/28 14:33:20
@Author:    chenchunhu
@Version:   1.0
@Contact:   wb-cch358909@alibaba-inc.com
@License:   Mulan PSL v2
@Modify:    chenchunhu
"""

from common.basetest import LocalTest

class Test(LocalTest):
    """
    See tc_lmdb_lmdb_func_004.yaml for details

    :avocado: tags=P2,noarch,local
    """

    PARAM_DIC = {"pkg_name": "lmdb lmdb-devel gcc valgrind"}
    def setUp(self):
        super().setUp(self.PARAM_DIC)
        cmdline = '''cat >lmdb_test5.c<<"EOF"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "lmdb.h"

#define DATABASE_PATH "lmdb_test5_db"

int main(int argc, char *argv[]) {
    MDB_env *env;
    MDB_txn *txn;
    MDB_dbi dbi;
    MDB_val key, data;
    int rc;
    long i, num_records = 1000000; // 测试 100 万条记录

    // 创建并配置LMDB环境
    mdb_env_create(&env);
    mdb_env_set_maxdbs(env, 1);
    mdb_env_set_mapsize(env, 1024L * 1024L * 1024L); // 设置地图尺寸为 1GB
    mdb_env_open(env, DATABASE_PATH, 0, 0664);

    // 创建一个写事务并打开数据库
    mdb_txn_begin(env, NULL, 0, &txn);
    mdb_dbi_open(txn, NULL, 0, &dbi);

    // 写入大量数据
    srand(time(NULL));
    for (i = 0; i < num_records; i++) {
        key.mv_size = sizeof(long);
        key.mv_data = &i;
        data.mv_size = sizeof(int);
        int rand_val = rand();
        data.mv_data = &rand_val;
        rc = mdb_put(txn, dbi, &key, &data, 0);
        if (rc != MDB_SUCCESS) {
            printf("Write failed: %s\\n", mdb_strerror(rc));
            mdb_txn_abort(txn);
            mdb_env_close(env);
            return 1;
        }
    }
    mdb_txn_commit(txn);
    printf("Finished writing %ld records.\\n", num_records);

    // 读取数据并检查内存泄漏
    mdb_txn_begin(env, NULL, MDB_RDONLY, &txn);
    for (i = 0; i < num_records; i++) {
        key.mv_size = sizeof(long);
        key.mv_data = &i;
        rc = mdb_get(txn, dbi, &key, &data);
        if (rc != MDB_SUCCESS) {
            printf("Read failed: %s\\n", mdb_strerror(rc));
        }
    }
    mdb_txn_abort(txn);
    printf("Finished reading %ld records.\\n", num_records);

    // 关闭数据库和环境
    mdb_dbi_close(env, dbi);
    mdb_env_close(env);

    return 0;
}
EOF'''
        self.cmd(cmdline)
        self.cmd("mkdir -p lmdb_test5_db")


    def test(self):
        self.cmd("gcc -o lmdb_test5 lmdb_test5.c -llmdb")
        self.cmd("valgrind --leak-check=full ./lmdb_test5 > lmdb.log 2>&1")
        code, lmdb_result = self.cmd("cat lmdb.log", ignore_status=True)
        self.assertIn("All heap blocks were freed -- no leaks are possible", lmdb_result)

    def tearDown(self):
        super().tearDown(self.PARAM_DIC)
        self.cmd("rm -rf lmdb_test5.c lmdb_test5 lmdb_test5_db")
